﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Compression;
using DBFile.Core.Web;
using System.IO;
using DBFile.Core.Interfaces;
using DBFile.Core.Impl;
using Ionic.Zip;

namespace DBFile.Core.Extensions
{
    static class CompressionExtensions
    {
        public static byte[] Decompress(this byte[] compressedBytes, string filename)
        {
            MemoryStream inStream = new MemoryStream(compressedBytes);
            MemoryStream outStream = new MemoryStream();

            Decompress(inStream, outStream, filename);

            return outStream.GetBuffer();
        }

        public static byte[] Compress(this byte[] decompressedBytes, string filename)
        {
            MemoryStream inStream = new MemoryStream(decompressedBytes);
            MemoryStream outStream = new MemoryStream();

            Compress(inStream, outStream, filename);

            return outStream.GetBuffer();
        }


        public static IDBFile Decompress(this IDBFile file)
        {
            IDBFile dbFile = new DBFileInfo();

            dbFile.ContentType = file.ContentType;
            dbFile.FileName = file.FileName;

            MemoryStream inStream = new MemoryStream(file.FileBytes);
            MemoryStream outStream = new MemoryStream();

            Decompress(inStream, outStream, file.FileName);

            byte[] decompressedBytes = outStream.GetBuffer();

            dbFile.ContentLength = outStream.Length;
            int length = (int)dbFile.ContentLength;

            dbFile.FileBytes = new byte[length];
            Array.Copy(decompressedBytes, dbFile.FileBytes, length);
            
            return dbFile;
        }

        public static IDBFile Compress(this IDBFile file)
        {
            IDBFile dbFile = new DBFileInfo();

            dbFile.ContentType = file.ContentType;
            dbFile.FileName = file.FileName;

            MemoryStream inStream = new MemoryStream(file.FileBytes);
            MemoryStream outStream = new MemoryStream();

            Compress(inStream, outStream, file.FileName);

            byte[] compressedBytes = outStream.GetBuffer();

            dbFile.ContentLength = outStream.Length;
            int length = (int)dbFile.ContentLength;

            dbFile.FileBytes = new byte[length];
            Array.Copy(compressedBytes, dbFile.FileBytes, length);

            return dbFile;
        }

        private static void Compress(Stream source, Stream destination, string filename)
        {
            using (ZipFile zip = new ZipFile())
            {
                zip.AddFileFromStream(filename, "", source);
                zip.Save(destination);
            }
        }

        private static void Decompress(Stream source, Stream destination, string filename)
        {
            
            using (ZipFile zip = ZipFile.Read(source))
            {
                foreach (ZipEntry entry in zip)
                {
                    zip.Extract(filename, destination);
                }
            }
            

        }

        //private static void Pump(Stream input, Stream output)
        //{
        //    byte[] bytes = new byte[4096];
        //    int n;
        //    while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
        //    {
        //        output.Write(bytes, 0, n);
        //    }
        //}


    }
}
